package com.fw.web.controller.system;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Objects;

import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fw.common.AliComm;
import com.fw.core.domain.model.LoginUser;
import com.fw.enums.OrderState;
import com.fw.system.admin.domain.FwShop;
import com.fw.system.admin.domain.FwSpu;
import com.fw.system.admin.domain.FwUser;
import com.fw.system.admin.domain.vo.AddrsVo;
import com.fw.system.admin.service.*;
import com.fw.utils.ServletUtils;
import com.fw.web.web.service.TokenService;
import io.swagger.annotations.Api;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import com.fw.annotation.Log;
import com.fw.core.controller.BaseController;
import com.fw.core.domain.AjaxResult;
import com.fw.enums.BusinessType;
import com.fw.system.admin.domain.FwOrder;
import com.fw.utils.poi.ExcelUtil;
import com.fw.core.page.TableDataInfo;

/**
 * 订单Controller
 *
 * @author yanwei
 * @date 2021-05-10
 */
@RestController
@RequestMapping("/admin/order")
@Log4j2
@Api(tags = "")
public class FwOrderController extends BaseController {

    private final IFwOrderService fwOrderService;
    private final TokenService tokenService;
    private final ISysUserService sysUserService;
    private final IFwUserService userService;
    @Autowired
    private AliComm aliComm;
    @Autowired
    private IFwAddrsService addrsService;
    @Autowired
    private IFwSpuService spuService;
    @Autowired
    private IFwSkuService skuService;
    @Autowired
    private IFwShopService shopService;

    public FwOrderController( IFwUserService userService, IFwOrderService fwOrderService, TokenService tokenService, ISysUserService sysUserService) {
        this.fwOrderService = fwOrderService;
        this.tokenService = tokenService;
        this.sysUserService = sysUserService;
        this.userService = userService;
    }

    /**
     * 查询订单列表
     */
    @PreAuthorize("@ss.hasPermi('admin:order:list')")
    @GetMapping("/list")
    public TableDataInfo list(FwOrder fwOrder) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        String shopId = sysUserService.isShop(loginUser);
       if (org.apache.commons.lang3.StringUtils.isNotBlank(shopId)){
           fwOrder.setShopId(shopId);
       }

        startPage();
        List<FwOrder> list = orderListDate(fwOrder);
        return getDataTable(list);
    }

    /**
     * 导出订单列表
     */
    @PreAuthorize("@ss.hasPermi('admin:order:export')")
    @Log(title = "订单", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(FwOrder fwOrder) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        String shopId = sysUserService.isShop(loginUser);
        fwOrder.setShopId(shopId);

        List<FwOrder> list = orderListDate(fwOrder);
        ExcelUtil<FwOrder> util = new ExcelUtil<>(FwOrder.class);
        return util.exportExcel(list, "order");
    }

    private List<FwOrder> orderListDate(FwOrder fwOrder) {
        List<Object> userIdList = null;
        if (StringUtils.isNotEmpty(fwOrder.getPhone()) || StringUtils.isNotEmpty(fwOrder.getUserName())) {
            userIdList = userService.listObjs(Wrappers.<FwUser>lambdaQuery()
                    .like(StringUtils.isNotEmpty(fwOrder.getPhone()), FwUser::getPhone, fwOrder.getPhone())
                    .like(StringUtils.isNotEmpty(fwOrder.getUserName()), FwUser::getUserName, fwOrder.getUserName()));
            //防止为空时跳过 in
            if ( userIdList.size() == 0) {
                userIdList.add( "" );
            }
        }

        //商品标题
        List<Object> spuIdList = null;
        if (StringUtils.isNotEmpty( fwOrder.getSpuTitle() )) {
            spuIdList = spuService.listObjs(Wrappers.<FwSpu>lambdaQuery().like(FwSpu::getTitle, fwOrder.getSpuTitle()));
            if (spuIdList.size() == 0) { spuIdList.add( "" ); }
        }

        List<FwOrder> list = fwOrderService.list(Wrappers.<FwOrder>lambdaQuery()
                .in(userIdList != null, FwOrder::getUserId, userIdList)
                .in(spuIdList!=null, FwOrder::getSpuId, spuIdList)
                .eq(StringUtils.isNotEmpty(fwOrder.getShopId()), FwOrder::getShopId, fwOrder.getShopId())
                .eq(fwOrder.getStatus()!= null, FwOrder::getStatus, fwOrder.getStatus())
                .eq(fwOrder.getAfterSaleState()!= null, FwOrder::getAfterSaleState, fwOrder.getAfterSaleState())
                .like(StringUtils.isNotEmpty(fwOrder.getCourierName()), FwOrder::getCourierName, fwOrder.getCourierName())
                .like(StringUtils.isNotEmpty(fwOrder.getCourierNumber()), FwOrder::getCourierNumber, fwOrder.getCourierNumber())
                .ge(fwOrder.getCreateTimeBegin()!=0, FwOrder::getCreateTime,
                        LocalDateTime.ofInstant(Instant.ofEpochMilli(fwOrder.getCreateTimeBegin()), ZoneOffset.of("+8")) )
                .le(fwOrder.getCreateTimeEnd()!=0, FwOrder::getCreateTime,
                        LocalDateTime.ofInstant(Instant.ofEpochMilli(fwOrder.getCreateTimeEnd()), ZoneOffset.of("+8")))
                .eq(fwOrder.getIsQuiz() != null, FwOrder::getIsQuiz, fwOrder.getIsQuiz())
                .eq(FwOrder::getRemoveFlag, 0)
                .orderByDesc(FwOrder::getCreateTime));
        for (FwOrder order : list) {
            order.setSpu( spuService.getById(order.getSpuId()) );
//            order.setSku( skuService.getById(order.getSkuId()) );
            //用户信息
            FwUser user = userService.getById(order.getUserId());
            if (user == null) {
                break;
            }
            order.setUserName(user.getUserName());
            order.setPhone( user.getPhone() );
            //地址信息
            if (StringUtils.isEmpty(order.getAddrString()) && StringUtils.isNotEmpty(order.getAddrId())) {
                AddrsVo voById = addrsService.getVoById(order.getAddrId());
                if (voById != null) {
                    order.setAddrString(voById.getContactName() + "&-fw-&" +
                            voById.getContactPhone() + "&-fw-&" +
                            voById.getProvinceName() +
                            voById.getAreaName() +
                            voById.getCityName() +
                            voById.getAddrInfo());
                    fwOrderService.update(Wrappers.<FwOrder>lambdaUpdate()
                            .set(FwOrder::getAddrString, order.getAddrString())
                            .eq(FwOrder::getId, order.getId()));
                }
            }
            if (StringUtils.isNotEmpty(order.getAddrString())) {
                String[] split = order.getAddrString().split("&-fw-&");
                order.setContactName(split[0]);
                order.setContactPhone(split[1]);
                order.setAddrInfo(split[2]);
            }
        }
        return list;
    }

    /**
     * 获取订单详细信息
     */
    @PreAuthorize("@ss.hasPermi('admin:order:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        FwOrder order = fwOrderService.getById(id);
        order.setSpu( spuService.getById(order.getSpuId()) );
        order.setSku( skuService.getById(order.getSkuId()) );
        //用户信息
        FwUser user = userService.getById(order.getUserId());
        order.setUserName(user.getUserName());
        order.setPhone( user.getPhone() );
        //地址信息
        if (StringUtils.isEmpty(order.getAddrString()) && StringUtils.isNotEmpty(order.getAddrId())) {
            AddrsVo voById = addrsService.getVoById(order.getAddrId());
            if (voById != null) {
                order.setAddrString(voById.getContactName() + "&-fw-&" +
                        voById.getContactPhone() + "&-fw-&" +
                        voById.getProvinceName() +
                        voById.getAreaName() +
                        voById.getCityName() +
                        voById.getAddrInfo());
            }
        }
        if (StringUtils.isNotEmpty(order.getAddrString())) {
            String[] split = order.getAddrString().split("&-fw-&");
            order.setContactName(split[0]);
            order.setContactPhone(split[1]);
            order.setAddrInfo(split[2]);
        }
        return AjaxResult.success(order);
    }

    /**
     * 新增订单
     */
    @PreAuthorize("@ss.hasPermi('admin:order:add')")
    @Log(title = "订单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody FwOrder fwOrder) {
        return toAjax(fwOrderService.insertFwOrder(fwOrder));
    }

    /**
     * 修改订单
     */
    @PreAuthorize("@ss.hasPermi('admin:order:edit')")
    @Log(title = "订单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody FwOrder fwOrder) {
        return toAjax(fwOrderService.updateFwOrder(fwOrder));
    }

    /**
     * 删除订单
     */
    @PreAuthorize("@ss.hasPermi('admin:order:remove')")
    @Log(title = "订单", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids) {
        return toAjax(fwOrderService.deleteFwOrderByIds(ids));
    }

    /**
     * @Effect 审批售后订单
     * @Author 姚
     * @Date 2021/7/12
     **/
    @PreAuthorize("@ss.hasPermi('admin:order:approvalOrder')")
    @Log(title = "审批订单", businessType = BusinessType.UPDATE)
    @PostMapping("/approvalOrder")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult approvalOrder(@RequestBody FwOrder fwOrder) {
        FwOrder oldOrder = fwOrderService.getById(fwOrder.getId());
        if (!oldOrder.getStatus().equals(OrderState.AFTER_SALE.getCode()) || !Integer.valueOf(1).equals(oldOrder.getAfterSaleState()) ) {
            return AjaxResult.error("该订单无需审批");
        }
        if (OrderState.AFTER_SALE_REJECT.getCode().equals( fwOrder.getAfterSaleState() )
                && StringUtils.isEmpty(fwOrder.getAfterSaleRemark())) {
            return AjaxResult.error("请输入拒绝原因");
        }
        if (fwOrder.getAfterSaleState() == 2) {
            //同意退款
            log.info("退款订单号："+ fwOrder.getId());
            FwOrder order = fwOrderService.getById(fwOrder.getId());
            FwUser user = userService.getById(order.getUserId());
            try {
                aliComm.aliTransfer(user.getAliPhone(), order.getTotalPrice(), user.getAliUserName());
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            fwOrderService.update(Wrappers.<FwOrder>lambdaUpdate()
                    .set(FwOrder::getAfterSaleState, fwOrder.getAfterSaleState())
                    .set(FwOrder::getUpdateTime, LocalDateTime.now())
                    .eq(FwOrder::getId, fwOrder.getId()));
        } else if (fwOrder.getAfterSaleState() == 3) {
            if (StringUtils.isEmpty(fwOrder.getCourierNumber())) {
                fwOrder.setStatus( OrderState.TO_BE_DELIVERED.getCode() );
            } else {
                fwOrder.setStatus( OrderState.TO_BE_RECEIVED.getCode() );
            }
            fwOrderService.update(Wrappers.<FwOrder>lambdaUpdate()
                    .set(FwOrder::getAfterSaleState, fwOrder.getAfterSaleState())
                    .set(FwOrder::getAfterSaleRemark, fwOrder.getAfterSaleRemark())
                    .set(FwOrder::getStatus, fwOrder.getStatus())
                    .set(FwOrder::getUpdateTime, LocalDateTime.now())
                    .eq(FwOrder::getId, fwOrder.getId()));
        }

        return AjaxResult.success("成功审批售后订单");
    }

    /** 更新快递单号 */
    @PreAuthorize("@ss.hasPermi('admin:order:updateCourierNumber')")
    @Log(title = "更新快递单号", businessType = BusinessType.UPDATE)
    @PostMapping("/updateCourierNumber")
    public AjaxResult updateCourierNumber(@RequestBody FwOrder fwOrder){
        FwOrder oldOrder = fwOrderService.getById(fwOrder.getId());
        if (!oldOrder.getStatus().equals(OrderState.TO_BE_DELIVERED.getCode())) {
            return AjaxResult.error("非待发货订单不可更新快递信息");
        }
        if (StringUtils.isNotEmpty(oldOrder.getCourierName()) && StringUtils.isNotEmpty(oldOrder.getCourierNumber())) {
            return AjaxResult.error("已存在快递信息");
        }
        if (StringUtils.isEmpty(fwOrder.getCourierName()) || StringUtils.isEmpty(fwOrder.getCourierNumber())) {
            return AjaxResult.error("运单编号或运单公司名称不可为空");
        }
        //更新快递信息
        fwOrderService.update(Wrappers.<FwOrder>lambdaUpdate()
                .set(FwOrder::getCourierName, fwOrder.getCourierName())
                .set(FwOrder::getCourierNumber, fwOrder.getCourierNumber())
                .set(FwOrder::getUpdateTime, LocalDateTime.now())
                .set(FwOrder::getStatus, OrderState.TO_BE_RECEIVED.getCode())
                .eq(FwOrder::getId, fwOrder.getId()));

        //给商户发钱
        if (oldOrder.getIsQuiz() == 1) {
            FwShop shop = shopService.getById(oldOrder.getShopId());
            if (shop == null) {
                log.error("订单号"+ oldOrder.getId() +"为商户付款时商铺不存在，商铺ID=>"+oldOrder.getShopId());
                return AjaxResult.error("订单号"+ oldOrder.getId() +"为商户付款时商铺不存在，商铺ID=>"+oldOrder.getShopId()) ;
            }
            FwUser user = userService.getById(shop.getUserId());
            if (user == null) {
                log.error("订单号"+ oldOrder.getId() +"为商户付款时商户不存在，商户ID=>"+shop.getUserId());
                return AjaxResult.error("订单号"+ oldOrder.getId() +"为商户付款时商户不存在，商户ID=>"+shop.getUserId()) ;
            }

            //计算给多少钱
            FwSpu spu = spuService.getById(oldOrder.getSpuId());
            BigDecimal shopMoney = spu.getRealPrice().subtract( spu.getPrice() ).multiply( BigDecimal.valueOf(oldOrder.getSpuNumber()) );

            try {
                aliComm.aliTransfer(user.getAliPhone(), shopMoney, user.getAliUserName());
            } catch (AlipayApiException e) {
                return AjaxResult.error(e.getMessage());
            }
        }
        return AjaxResult.success("成功更新快递单号");
    }
}
